package dev.ece.suit.hexmap;

import java.io.InputStream;
import java.util.Map;

import org.lwjgl.opengl.GL20;

import dev.ece.core.light.Material;
import dev.ece.core.light.MaterialLocationHandler;
import dev.ece.core.shader.Shader;
import dev.ece.core.texture.Texture;
import dev.ece.suit.utils.ShaderFunctions;

public class HexMapTriangleShader extends Shader {

	public HexMapTriangleShader(InputStream vertexShaderInputStream,
			InputStream pixelShaderInputStream, Map<String, String> functions) {
		super(vertexShaderInputStream, pixelShaderInputStream, functions);
	}

	@Override
	protected String getVertexHeader() {
		StringBuffer s = new StringBuffer();
		s.append(Material.getMaterialStructString());
		s.append(super.getVertexHeader());
		return s.toString();
	}

	@Override
	protected String getPixelHeader() {
		return this.getVertexHeader();
	}
	
	@Override
	protected String getVersion() {
		return "#version 330 core";
	}
	
	private MaterialLocationHandler material1LocationHanlder;
	
	private MaterialLocationHandler material2LocationHanlder;
	
	private MaterialLocationHandler material3LocationHanlder;
	
	
	private int texture1Handler;
	
	private int texture2Handler;
	
	private int texture3Handler;
	
	@Override
	protected void onBindAttribLocations(int program) {
		GL20.glBindAttribLocation(program, 0, "ece_Vertex");
		GL20.glBindAttribLocation(program, 1, "ece_TexCoord");
		GL20.glBindAttribLocation(program, 2, "ece_Normal");
		GL20.glBindAttribLocation(program, 3, "ece_TexAlpha");
	}

	@Override
	protected void onInitializeHandler(int program) {
		material1LocationHanlder = MaterialLocationHandler.newInstance(program, "material1.");
		material2LocationHanlder = MaterialLocationHandler.newInstance(program, "material2.");
		material3LocationHanlder = MaterialLocationHandler.newInstance(program, "material3.");
		texture1Handler = GL20.glGetUniformLocation(program, "texture1");
		texture2Handler = GL20.glGetUniformLocation(program, "texture2");
		texture3Handler = GL20.glGetUniformLocation(program, "texture3");
	}

	public void glTexture(Texture texture1, Texture texture2, Texture texture3) {
		GL20.glUniform1i(texture1Handler, texture1.bind(1));
		GL20.glUniform1i(texture2Handler, texture2.bind(2));
		GL20.glUniform1i(texture3Handler, texture3.bind(3));
	}
	
	public void glMaterial(Material material1, Material material2, Material material3) {
		material1.glUniformMaterial(material1LocationHanlder);
		material2.glUniformMaterial(material2LocationHanlder);
		material3.glUniformMaterial(material3LocationHanlder);
	}
	
	@Override
	public void clearup() {
		material1LocationHanlder.clearup();
		material2LocationHanlder.clearup();
		material2LocationHanlder.clearup();
		GL20.glDeleteShader(texture1Handler);
		GL20.glDeleteShader(texture2Handler);
		GL20.glDeleteShader(texture3Handler);
		super.clearup();
		material1LocationHanlder = null;
		material2LocationHanlder = null;
		material3LocationHanlder = null;
	}

	private static HexMapTriangleShader hexMapTriangleShader;
	
	public static HexMapTriangleShader createHexMapTriangleShader() {
		if(hexMapTriangleShader == null) {
			hexMapTriangleShader = new HexMapTriangleShader(
					HexMapTriangleShader.class.getClassLoader().getResourceAsStream("shaders/defer/hexmaptriangle.vert"),
					HexMapTriangleShader.class.getClassLoader().getResourceAsStream("shaders/defer/hexmaptriangle.frag"), 
					ShaderFunctions.getFunctions());
		}
		return hexMapTriangleShader;
	}
	
}
